package com.laboratory.websocketlearning.interceptor;

import jakarta.servlet.http.HttpSession;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import java.util.Map;

/**
 * HandshakeInterceptor 是 Spring WebSocket 框架中的一个接口，用于在 WebSocket 握手阶段进行拦截和处理。它的主要作用包括：
 * 握手前处理：
 * 在 WebSocket 连接建立之前执行
 * 可以进行身份验证、权限检查等操作
 * 根据业务逻辑决定是否允许连接建立
 * 握手后处理：
 * 在 WebSocket 连接建立之后执行
 * 可以进行一些后置处理操作
 * 核心方法：
 * beforeHandshake()：握手前调用，返回 true 允许连接，返回 false 拒绝连接
 * afterHandshake()：握手后调用，通常用于清理工作
 */
@Component
public class AuthHandshakeInterceptor implements HandshakeInterceptor {

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
        System.out.println("beforeHandshake");
        String query = request.getURI().getQuery();
        if (query != null && query.contains("user=")) {
            String user = query.replaceAll(".*user=([^&]+).*", "$1");
            attributes.put("user", user);
        }
        if (request instanceof ServletServerHttpRequest servletServerHttpRequest) {
            /**
             * 获取当前HTTP请求的会话对象(HttpSession)，用于检查用户是否已登录。
             * 通过ServletRequest获取Session，参数false表示如果不存在session则返回null而不创建新session。
             */
            HttpSession httpSession = servletServerHttpRequest.getServletRequest().getSession(false);
            if (httpSession != null && httpSession.getAttribute("uid") != null) {
                attributes.putIfAbsent("user", String.valueOf(httpSession.getAttribute("uid")));
            }
        }
        return true;
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
        System.out.println("afterHandshake");
    }

}
